﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Reflection.Core;
using System.Reflection;
using Pixysoft.Framework.Reflection.Controller;

namespace Pixysoft.Framework.Reflection.testdriven
{
    class Class_dummy_performance
    {
        //code dynamic serialize
        public void test002()
        {
            //------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

            //reflection
            //    Time Elapsed:		4,364ms
            //    CPU time:		4,171,875,000ns
            //    Gen 0: 			449
            //    Gen 1: 			0
            //    Gen 2: 			0

            //dynamic
            //    Time Elapsed:		1,067ms
            //    CPU time:		1,031,250,000ns
            //    Gen 0: 			18
            //    Gen 1: 			8
            //    Gen 2: 			2


            //1 passed, 0 failed, 0 skipped, took 5.58 seconds (Ad hoc).


            ObjectWithValueAndAttribute p = new ObjectWithValueAndAttribute();
            p.Age = 1;
            p.Name = "123";
            p.Price = 12;
            p.Type = PersonType.A;

            Pixysoft.Tools.CodeTimer.Initialize();

            Pixysoft.Tools.CodeTimer.Time("reflection", 100000, delegate()
             {
                 ReflectionSerialize(p);
             });

            Pixysoft.Tools.CodeTimer.Time("dynamic", 100000, delegate()
             {
                 DynamicSerializeObject(p);
             });
        }

        //compare object performance
        public void test005_peformance()
        {
            //------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

            //reflection
            //    Time Elapsed:		4,728ms
            //    CPU time:		4,625,000,000ns
            //    Gen 0: 			603
            //    Gen 1: 			0
            //    Gen 2: 			0

            //emit with handler cache
            //    Time Elapsed:		130ms
            //    CPU time:		125,000,000ns
            //    Gen 0: 			11
            //    Gen 1: 			0
            //    Gen 2: 			0


            //1 passed, 0 failed, 0 skipped, took 5.00 seconds (Ad hoc).




            ObjectWithValueAndAttribute p = new ObjectWithValueAndAttribute();
            p.Age = 1;
            p.Name = "123";
            p.Price = 12;
            p.Type = PersonType.A;

            Pixysoft.Tools.CodeTimer.Initialize();

            Pixysoft.Tools.CodeTimer.Time("reflection", 100000, delegate()
            {
                ReflectionSerialize(p);
            });

            Pixysoft.Tools.CodeTimer.Time("emit with handler cache", 100000, delegate()
             {
                 ReflectionManager.CreateDummyType(p.GetType());
             });
        }

        public void test006()
        {
            //------ Test started: Assembly: Pixysoft.Framework.Reflection.dll ------

            //reflection
            //    Time Elapsed:		278ms
            //    CPU time:		250,000,000ns
            //    Gen 0: 			73
            //    Gen 1: 			0
            //    Gen 2: 			0

            //emit with handler cache
            //    Time Elapsed:		307ms
            //    CPU time:		296,875,000ns
            //    Gen 0: 			19
            //    Gen 1: 			0
            //    Gen 2: 			0


            //1 passed, 0 failed, 0 skipped, took 0.75 seconds (Ad hoc).


            //测试获取property

            ObjectWithValueAndAttribute p = new ObjectWithValueAndAttribute();
            p.Age = 1;
            p.Name = "123";
            p.Price = 12;
            p.Type = PersonType.A;

            Pixysoft.Tools.CodeTimer.Initialize();

            Pixysoft.Tools.CodeTimer.Time("reflection", 100000, delegate()
            {
                foreach (PropertyInfo info in p.GetType().GetProperties())
                {
                    string name = info.Name;
                    Type type = info.PropertyType;
                }

                foreach (MethodInfo info in p.GetType().GetMethods())
                {
                    string name = info.Name;
                    Type type = info.ReturnType;
                }

            });

            Pixysoft.Tools.CodeTimer.Time("emit with handler cache", 100000, delegate()
            {
                foreach (IDummyPropertyInfo info in ReflectionManager.CreateDummyType(p.GetType()).GetProperties())
                {
                    string name = info.Name;
                    IDummyType type = info.PropertyType;
                }

                foreach (IDummyMethodInfo info in ReflectionManager.CreateDummyType(p.GetType()).GetMethods())
                {
                    string name = info.Name;
                    IDummyType type = info.ReturnType;
                }
            });
        }


        public DummyType ReflectionSerialize(object person)
        {
            Type type = person.GetType();
            DummyType dummy = new DummyType(type.Namespace, type.FullName, type.Name);
            dummy.DataType = DotNetDataType.UNKNOWN;
            dummy.PropertyType = DotNetPropertyType.Object;
            dummy.DeclaringType = null;

            foreach (PropertyInfo info in person.GetType().GetProperties())
            {
                IDummyPropertyInfo property = dummy.CreateProperty(info.Name, info.CanRead, info.CanWrite);

                if (info.PropertyType.IsEnum)
                {
                    property.PropertyType = ReflectionEnumSerialize(info.PropertyType.Namespace, info.PropertyType.FullName, info.PropertyType.Name,
                        info.GetValue(person, null));
                }
                else if (info.PropertyType.IsValueType)
                {
                    property.PropertyType = ReflectionValueSerialize(info.PropertyType.FullName, info.PropertyType.Name,
                        Pixysoft.Tools.ParserHelper.GetDataTypeByType(info.PropertyType), info.GetValue(person, null));
                }
                else if (info.PropertyType.Equals(typeof(string)))
                {
                    property.PropertyType = ReflectionValueSerialize(info.PropertyType.FullName, info.PropertyType.Name,
       Pixysoft.Tools.ParserHelper.GetDataTypeByType(info.PropertyType), info.GetValue(person, null));
                }
            }
            return dummy;
        }

        private DummyType ReflectionEnumSerialize(string nameSpace, string fullname, string name, object value)
        {
            DummyType dummy = new DummyType(nameSpace,
                  fullname, name);
            dummy.DataType = DotNetDataType.UNKNOWN;
            dummy.PropertyType = DotNetPropertyType.Enum;
            dummy.DeclaringType = null;
            return dummy;
        }

        private DummyType ReflectionValueSerialize(string fullname, string name, DotNetDataType datatype, object value)
        {
            DummyType dummy = new DummyType("System",
                  fullname, name);
            dummy.DataType = datatype;
            dummy.PropertyType = DotNetPropertyType.Value;
            dummy.DeclaringType = null;
            return dummy;
        }

        public IDummyType DynamicSerializeObject(ObjectWithValueAndAttribute obj)
        {
            DummyType type = DummyTypeHandlerFactory.CreateDummyTypeObject("PIxysoft", "adf", "asdf", obj.GetType()) as DummyType;
            type.CreateProperty("Age", true, true).PropertyType = DummyTypeHandlerFactory.CreateDummyTypeValue("123", "123", DotNetDataType.Int32);
            type.LastProperty().AddAttribute(new SomeAttribute(null, "123", -256, 0, true, 1, long.MaxValue, char.MaxValue, PersonType.B));
            type.CreateProperty("Price", true, true).PropertyType = DummyTypeHandlerFactory.CreateDummyTypeValue("123", "123", DotNetDataType.Double);
            return type;
        }
    }
}
